# gameplay/cards/generators/CardGenerator.gd 类脚本（三角形布局算法）
class_name CardGenerator

var card_pool := []
var enymy_area := []
var card_interaction :CardInteraction = CardInteraction.new()
var card_effect :CardEffectResolver = CardEffectResolver.new()

#敌人卡牌生成
func generate_enemy_card(card_manager : CardManager) -> void:
	for enemy in range(GlobalConstants.ENEMY_COUNT):
		var enemy_card =  _create_card(GlobalConstants.MAX_LAYERS , enemy)
		card_manager.add_child(enemy_card)
		enemy_card.name = String("enemy_card%02d"%enemy)
		_add_card_to_area(enemy_card)
	
func _add_card_to_area(card:CardBase) :
	enymy_area.insert(0,card)
	card.set_collision_layer_value(GlobalConstants.MAX_LAYERS + 1 ,true)
	card.set_collision_mask_value(GlobalConstants.MAX_LAYERS + 2 ,true)
	_update_enemy_position()

func _update_enemy_position():
	for i in range(enymy_area.size()):
		var new_position = Vector2(_calculate_enemy_position(i),GlobalConstants.ENEMY_Y_POS)
		var card = enymy_area[i]
		card_effect.animate_card_to_pos(card,new_position)
		_setup_card_position(card,new_position)

func _calculate_enemy_position(index):
	var x_offset = (enymy_area.size() - 1 ) * GlobalConstants.CARD_WIDTH
	var x_pos = GlobalConstants.viewport_size.x / 2 + index * GlobalConstants.CARD_WIDTH - x_offset / 2 
	return x_pos
	
#景区卡牌生成
func generate_scenic_card_layers(card_manager : CardManager) -> void:
	# 初始化根卡牌
	var root_card := _create_card(0, 0)
	card_manager.add_child(root_card)
	#root_card.collision_mask_for_children = 0b10  # 仅检测layer_1
	root_card.collision_layer = 1
	root_card.collision_mask = 2
	root_card.name = String("scenic_card%02d"%00)
	_setup_card_position(root_card, _calculate_root_position(card_manager))
	# 生成卡牌布局
	for current_layer in range(1, GlobalConstants.MAX_LAYERS):
		var card_count = current_layer + 1  # 当前层卡牌数
		var parent_layer := current_layer - 1
		var parents := card_manager.get_tree().get_nodes_in_group("layer_%d" % parent_layer)
		var parent := parents[0]
		var pos :Vector2 = parent.position + Vector2( - parent.size.x * 0.8, GlobalConstants.VERTICAL_SPACING)
		var is_last_layer : = false
		var children : Array[CardBase]= []
		if current_layer == GlobalConstants.MAX_LAYERS - 1:
			is_last_layer = true
		#改为根据最大卡牌数限制
		for count in card_count:
			var child := _create_child_cards(card_manager,pos, current_layer, count, is_last_layer)
			if count != card_count - 1:
				var children_null : Array[CardBase]= []
				card_manager.scenic_card_hierarchy[parents[count]] = children_null #Array[CardBase]占位符
				card_manager.scenic_card_hierarchy[parents[count]].append(child) #先赋值左侧关系一次
				child.parents.append(parents[count])
			children.append(child)
			pos = Vector2( pos.x + parent.size.x*1.6, pos.y)
		#print("card_manager.scenic_card_hierarchy->left_part :",card_manager.scenic_card_hierarchy)	
		_setup_layer_child_relation(card_manager.scenic_card_layer, current_layer, children) 
		#补充处理父子节点relation--
		children.reverse()
		var index_parents : int = current_layer - 1
		for child in children:
			var parent_relation = parents[index_parents]
			card_manager.scenic_card_hierarchy[parent_relation].append(child)#补充赋值右侧关系一次
			child.parents.append(parent_relation)
			#print("card_manager.scenic_card_hierarchy->right_part :",card_manager.scenic_card_hierarchy)
			if index_parents == 0 :
				break
			else :
				index_parents -= 1
			
func _create_card(layer: int, index: int ) -> CardBase:
	# 在card_manager中复用卡牌实例
	var card: CardBase
	if not card_pool.is_empty():
		card = card_pool.pop_back()
		# 断开旧信号连接
		_EventBus.disconnect_func_signal(_EventBus.card_clicked,card_interaction.handle_click)
	else:
		card = GlobalConstants.CARD_SCENE.instantiate()
	card.initialize(_generate_card_data(layer, index))
	card.layer = layer  # 传递层级
	card.z_index = layer  # 确保高层级卡牌渲染在上层
	card.add_to_group("layer_%d" % layer)  # 确保添加层级组
	card.add_to_group("cards")  # 确保添加cards组
	#信号连接处理函数
	_EventBus.connect_func_signal(_EventBus.card_clicked, card_interaction.handle_click)
	_EventBus.connect_func_signal(_EventBus.card_hovered, card_interaction.on_card_hovered)
	_EventBus.connect_func_signal(_EventBus.card_hovered_off, card_interaction.on_card_hovered_off)
	#if card.get_tree().get_nodes_in_group("cards").size() >= GlobalConstants.MAX_CARD_INSTANCES:
		#push_error("Card instance limit reached!")
		#return null
	return card
	
func _create_child_cards(card_manager:CardManager ,pos: Vector2, current_layer: int,count :int , is_last_layer : bool ) -> CardBase:
	var child : CardBase = _create_card(current_layer,count)
	child.set_collision_layer_value(current_layer + 1 ,true)
	child.set_collision_mask_value(current_layer + 2 ,true)
	if is_last_layer :
		child.current_state = CardBase.State.ACTIVE  # 直接激活
	_setup_card_position(child ,pos,count)
	card_manager.add_child(child)
	child.name = String("scenic_card%02d"%count)
	return child
	
func _calculate_root_position(card_manager:CardManager) -> Vector2:
	var viewport_size := card_manager.get_viewport_rect().size
	# 使用实际卡牌尺寸计算，而非base_card_size
	return Vector2(
		(viewport_size.x/2 ) ,  # 横向居中- root_size.x/2
		200  # 纵向起始位置
	)
	
func _generate_card_data(layer: int, _index: int) -> CardData:
	var card_data := CardData.new()
	# 使用PRD算法控制概率分布
	var type_weights := {
		CardData.Type.ENVIRONMENT: _calculate_weight(layer, 0.6),
		CardData.Type.ENEMY: _calculate_weight(layer, 0.3),
		CardData.Type.RESOURCE: _calculate_weight(layer, 0.1)
	}
	# 权重随机算法
	var total_weight: float = type_weights.values().reduce(func(a, b): return a + b)
	var roll := randf_range(0.0, total_weight)
	var cumulative := 0.0
	for type in type_weights:
		cumulative += type_weights[type]
		if roll <= cumulative:
			card_data.type = type
			break
	# 动态生成数值
	card_data.stamina_cost = _calculate_stamina_cost(layer, card_data.type)
	card_data.eco_value = _calculate_eco_value(layer, card_data.type)
	return card_data
	
func _setup_card_position(card: CardBase, pos: Vector2 , _index : int = 0) -> void:
	card.position = pos 
	#print("Card at layer %d index %d : %s object_id : %s" % [card.layer, _index ,pos , card.get_instance_id()])
	#print("collision_pos at : %s" % [card.get_node("CollisionShape2D").global_position])
	
func _setup_layer_child_relation(card_layer:Dictionary,layer: int,children: Array[CardBase]) -> void:
	card_layer[layer] = children

# 辅助方法
func _calculate_weight(layer: int, base: float) -> float:
	return clamp(base - layer * 0.05, 0.1, 1.0)
	
func _calculate_stamina_cost(layer: int, type: CardData.Type) -> float:
	var base_value: float = 0.0
	match type:
		CardData.Type.ENVIRONMENT:
			base_value = 12.0
		CardData.Type.ENEMY:
			base_value = 15.0
		CardData.Type.RESOURCE:
			base_value = 8.0
		_:
			push_error("Invalid card type: %s" % type)
			return 0.0
	var layer_multiplier: float = 1.0 + (layer * 0.1)
	return base_value * layer_multiplier

func _calculate_eco_value(layer: int, type: CardData.Type) -> int:
	var base_value: int = 0
	match type:
		CardData.Type.ENVIRONMENT:
			base_value = 10 + layer * 2
		CardData.Type.ENEMY:
			base_value = 5 + layer * 1
		CardData.Type.RESOURCE:
			base_value = 15 + layer * 3
		_:
			push_error("Invalid card type: %s" % type)
			return 0
	return base_value

func prewarm_pool() -> void:
	var pregen_count :int = GlobalConstants.MAX_LAYERS * (GlobalConstants.MAX_LAYERS + 1) / 2 +  GlobalConstants.ENEMY_COUNT # 等差数列求和公式
	for i in pregen_count:
		var card := GlobalConstants.CARD_SCENE.instantiate()
		card_pool.append(card)
